package weiyao.xinxidasai.config.Redis;

import java.util.*;

import cn.hutool.core.collection.ConcurrentHashSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import weiyao.xinxidasai.mapper.VersionMapper;

import javax.annotation.PostConstruct;

@Component
public class BloomFilter {
    @Autowired
    private VersionMapper versionMapper;

    private static final double LN2 = Math.log(2);
    private static final double LN2_SQUARED = LN2 * LN2;

    private final BitSet bitSet;
    private final int[] seeds;
    private final int hashCount;
    private final int bitSetSize;

    // 添加状态跟踪变量
    private int elementCount = 0;

    public BloomFilter() {
        this(100_000, 0.01);
    }

    public BloomFilter(int capacity) {
        this(capacity, 0.01);
    }

    public BloomFilter(int capacity, double falsePositiveRate) {
        // 验证参数有效性
        if (capacity <= 0) {
            throw new IllegalArgumentException("Capacity must be positive");
        }
        if (falsePositiveRate <= 0 || falsePositiveRate >= 1) {
            throw new IllegalArgumentException("False positive rate must be between 0 and 1");
        }

        // 计算最优位数组大小和哈希函数数量
        this.bitSetSize = calculateBitSetSize(capacity, falsePositiveRate);
        this.hashCount = calculateHashCount(capacity, bitSetSize);

        // 初始化位数组和种子
        this.bitSet = new BitSet(bitSetSize);
        this.seeds = generateSeeds(hashCount);
    }
    @PostConstruct
    public void warmUp() {
        // 从数据库加载现有有效密钥
        List<String> existingKeys = versionMapper.getAllValidVersionNos();
        existingKeys.forEach(key -> this.add(key));
        System.out.println("布隆过滤器预热完成，加载密钥数量：" + existingKeys.size());
    }
    // BloomFilter 中的 add 方法示例
    public void add(String value) {
        for (int i = 0; i < hashCount; i++) {
            int hash = hash(value, seeds[i]);

            if (hash < 0 || hash >= bitSet.size()) {
                hash = Math.abs(hash) % bitSet.size(); // 取模避免越界
            }
            bitSet.set(hash);
        }
    }
    private int hash(String value, int seed) {
        int hash = Objects.hash(value, seed); // 直接使用String类型
        return Math.abs(hash) % bitSetSize;
    }

    public boolean mightContain(String value) {
        if (deletedKeys.contains(value)) {
            System.out.println("[DEBUG] 命中删除列表: " + value);
            return false;
        }

        for (int i = 0; i < hashCount; i++) {
            int hash = hash(value, seeds[i]);
            if (!bitSet.get(hash)) {
                System.out.println("[DEBUG] 位图未设置: value=" + value + ", hash=" + hash);
                return false;
            }
        }
        return true;
    }
    /**
     * 检查布隆过滤器是否为空
     *
     * 注意：布隆过滤器没有真正的"空"概念，此方法检查是否从未添加过任何元素
     *
     * @return 如果过滤器从未添加过元素返回 true，否则返回 false
     */
    public boolean isEmpty() {
        // 2. 高效但需要维护状态：使用计数器
        return elementCount == 0;

    }



    public void clear() {
        bitSet.clear();
        elementCount = 0; // 重置计数器
    }

    public int size() {
        return bitSetSize;
    }



    private int calculateBitSetSize(int n, double p) {
        return (int) Math.ceil(-(n * Math.log(p)) / LN2_SQUARED);
    }

    private int calculateHashCount(int n, int m) {
        return Math.max(1, (int) Math.round((double) m / n * LN2));
    }

    private int[] generateSeeds(int count) {
        int[] seeds = new int[count];
        Random random = new Random(System.currentTimeMillis());
        for (int i = 0; i < count; i++) {
            seeds[i] = random.nextInt();
        }
        return seeds;

    }

    public final Set<String> deletedKeys = new ConcurrentHashSet<>();

    public void delete(String value) {
        deletedKeys.add(value);
    }
}
